package com.shuai.baibi.aop;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;

@Aspect
@Component
@Slf4j
public class UserControllerAOP {
    /**
     * 配置拦截规则：拦击controller包下的所有方法
     */
    @Pointcut("execution(* com.shuai.baibi.controller.UserController.*(..))")
    public void userPointCut() {
    }


    /**
     * 环绕通知，针对UserController中的方法做请求参数日志统计以及方法执行时间的统计
     */
    @Around("userPointCut()")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();  // 开始计时
        Object[] requestArgs = joinPoint.getArgs(); // 获取请求参数
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        StringBuffer requestURL = request.getRequestURL();  // 请求的url
        String remoteHost = request.getRemoteHost();    // 请求用户的ip
        StringBuilder requestInfoBuilder = new StringBuilder();
        String requestID = UUID.randomUUID().toString().replace("-", "");
        requestInfoBuilder.append("\nrequestStart:\n[\n\trequestID: ")
                .append(requestID)
                .append("\n");
        requestInfoBuilder.append("\trequestHost: ").append(remoteHost).append("\n");
        requestInfoBuilder.append("\trequestURL: ")
                .append(requestURL)
                .append("\n");
        requestInfoBuilder.append("\trequestArgs: {")
                .append(StringUtils.join(requestArgs, ","))
                .append("}\n");
        requestInfoBuilder.append("]\n");
        log.info(requestInfoBuilder.toString());    // 请求参数记录

        StringBuilder processingInfoBuilder = new StringBuilder();
        Object result = joinPoint.proceed();// 执行原方法
        stopWatch.stop();   // 结束计时
        processingInfoBuilder.append("\nrequestEnd: \n[\n\trequestID: ")
                .append(requestID)
                .append("\n");
        processingInfoBuilder.append("\tprocessTimeMillis: ")
                .append(stopWatch.getTotalTimeMillis()) // 方法的执行时间
                .append("ms\n");
        processingInfoBuilder.append("]\n");
        log.info(processingInfoBuilder.toString());
        return result;
    }
}